/**
 * @file application.h
 * @brief 应用程序主类头文件
 * @details 定义了应用程序的核心功能和状态管理
 */
#ifndef _APPLICATION_H_
#define _APPLICATION_H_

#include <freertos/FreeRTOS.h>
#include <freertos/event_groups.h>
#include <freertos/task.h>
#include <esp_timer.h>

#include <string>
#include <mutex>
#include <list>

#include <opus_encoder.h>
#include <opus_decoder.h>
#include <opus_resampler.h>

#include "protocol.h"
#include "ota.h"
#include "background_task.h"

#if CONFIG_USE_WAKE_WORD_DETECT
#include "wake_word_detect.h"
#endif
#if CONFIG_USE_AUDIO_PROCESSOR
#include "audio_processor.h"
#endif

/**
 * @brief 调度事件标志
 */
#define SCHEDULE_EVENT (1 << 0)
/**
 * @brief 音频输入就绪事件标志
 */
#define AUDIO_INPUT_READY_EVENT (1 << 1)
/**
 * @brief 音频输出就绪事件标志
 */
#define AUDIO_OUTPUT_READY_EVENT (1 << 2)

/**
 * @brief 设备状态枚举
 */
enum DeviceState {
    kDeviceStateUnknown,       ///< 未知状态
    kDeviceStateStarting,      ///< 启动中
    kDeviceStateWifiConfiguring, ///< WiFi配置中
    kDeviceStateIdle,          ///< 空闲状态
    kDeviceStateConnecting,    ///< 连接中
    kDeviceStateListening,     ///< 监听中
    kDeviceStateSpeaking,      ///< 语音输出中
    kDeviceStateUpgrading,     ///< 升级中
    kDeviceStateActivating,    ///< 激活中
    kDeviceStateFatalError     ///< 致命错误
};

/**
 * @brief Opus编码帧持续时间(毫秒)
 */
#define OPUS_FRAME_DURATION_MS 60

/**
 * @brief 应用程序主类
 * @details 实现了设备的核心功能，包括状态管理、音频处理、通信协议等
 */
class Application {
public:
    /**
     * @brief 获取单例实例
     * @return Application& 应用程序实例引用
     */
    static Application& GetInstance() {
        static Application instance;
        return instance;
    }
    // 删除拷贝构造函数和赋值运算符
    Application(const Application&) = delete;
    Application& operator=(const Application&) = delete;

    /**
     * @brief 启动应用程序
     */
    void Start();
    
    /**
     * @brief 获取当前设备状态
     * @return DeviceState 当前设备状态
     */
    DeviceState GetDeviceState() const { return device_state_; }
    
    /**
     * @brief 检查是否检测到语音
     * @return bool 是否检测到语音
     */
    bool IsVoiceDetected() const { return voice_detected_; }
    
    /**
     * @brief 调度回调函数到主线程执行
     * @param callback 要执行的回调函数
     */
    void Schedule(std::function<void()> callback);
    
    /**
     * @brief 设置设备状态
     * @param state 新的设备状态
     */
    void SetDeviceState(DeviceState state);
    
    /**
     * @brief 显示提示信息
     * @param status 状态文本
     * @param message 消息内容
     * @param emotion 情感表达
     * @param sound 提示音效
     */
    void Alert(const char* status, const char* message, const char* emotion = "", const std::string_view& sound = "");
    
    /**
     * @brief 关闭提示信息
     */
    void DismissAlert();
    
    /**
     * @brief 中止语音输出
     * @param reason 中止原因
     */
    void AbortSpeaking(AbortReason reason);
    
    /**
     * @brief 切换聊天状态
     */
    void ToggleChatState();
    
    /**
     * @brief 开始监听
     */
    void StartListening();
    
    /**
     * @brief 停止监听
     */
    void StopListening();
    
    /**
     * @brief 更新物联网状态
     */
    void UpdateIotStates();
    
    /**
     * @brief 重启设备
     */
    void Reboot();
    
    /**
     * @brief 唤醒词触发
     * @param wake_word 检测到的唤醒词
     */
    void WakeWordInvoke(const std::string& wake_word);
    
    /**
     * @brief 播放音效
     * @param sound 音效资源
     */
    void PlaySound(const std::string_view& sound);
    
    /**
     * @brief 检查是否可以进入睡眠模式
     * @return bool 是否可以进入睡眠模式
     */
    bool CanEnterSleepMode();

private:
    /**
     * @brief 构造函数
     */
    Application();
    
    /**
     * @brief 析构函数
     */
    ~Application();

#if CONFIG_USE_WAKE_WORD_DETECT
    WakeWordDetect wake_word_detect_;  ///< 唤醒词检测器
#endif
#if CONFIG_USE_AUDIO_PROCESSOR
    AudioProcessor audio_processor_;   ///< 音频处理器
#endif
    Ota ota_;                          ///< OTA升级管理器
    std::mutex mutex_;                 ///< 互斥锁
    std::list<std::function<void()>> main_tasks_;  ///< 主线程任务队列
    std::unique_ptr<Protocol> protocol_;  ///< 通信协议
    EventGroupHandle_t event_group_ = nullptr;  ///< 事件组句柄
    esp_timer_handle_t clock_timer_handle_ = nullptr;  ///< 时钟定时器句柄
    volatile DeviceState device_state_ = kDeviceStateUnknown;  ///< 当前设备状态
    ListeningMode listening_mode_ = kListeningModeAutoStop;  ///< 监听模式
#if CONFIG_USE_REALTIME_CHAT
    bool realtime_chat_enabled_ = true;  ///< 实时聊天是否启用
#else
    bool realtime_chat_enabled_ = false;  ///< 实时聊天是否启用
#endif
    bool aborted_ = false;  ///< 是否已中止
    bool voice_detected_ = false;  ///< 是否检测到语音
    int clock_ticks_ = 0;  ///< 时钟计数
    TaskHandle_t main_loop_task_handle_ = nullptr;  ///< 主循环任务句柄
    TaskHandle_t check_new_version_task_handle_ = nullptr;  ///< 检查新版本任务句柄

    // 音频编码/解码
    TaskHandle_t audio_loop_task_handle_ = nullptr;  ///< 音频循环任务句柄
    BackgroundTask* background_task_ = nullptr;  ///< 后台任务
    std::chrono::steady_clock::time_point last_output_time_;  ///< 最后输出时间
    std::list<std::vector<uint8_t>> audio_decode_queue_;  ///< 音频解码队列

    std::unique_ptr<OpusEncoderWrapper> opus_encoder_;  ///< Opus编码器
    std::unique_ptr<OpusDecoderWrapper> opus_decoder_;  ///< Opus解码器

    OpusResampler input_resampler_;  ///< 输入重采样器
    OpusResampler reference_resampler_;  ///< 参考重采样器
    OpusResampler output_resampler_;  ///< 输出重采样器

    /**
     * @brief 主循环函数
     */
    void MainLoop();
    
    /**
     * @brief 音频输入处理
     */
    void OnAudioInput();
    
    /**
     * @brief 音频输出处理
     */
    void OnAudioOutput();
    
    /**
     * @brief 读取音频数据
     * @param data 音频数据缓冲区
     * @param sample_rate 采样率
     * @param samples 采样点数
     */
    void ReadAudio(std::vector<int16_t>& data, int sample_rate, int samples);
    
    /**
     * @brief 重置解码器
     */
    void ResetDecoder();
    
    /**
     * @brief 设置解码采样率
     * @param sample_rate 采样率
     * @param frame_duration 帧持续时间
     */
    void SetDecodeSampleRate(int sample_rate, int frame_duration);
    
    /**
     * @brief 检查新版本
     */
    void CheckNewVersion();
    
    /**
     * @brief 显示激活码
     */
    void ShowActivationCode();
    
    /**
     * @brief 时钟定时器回调
     */
    void OnClockTimer();
    
    /**
     * @brief 设置监听模式
     * @param mode 监听模式
     */
    void SetListeningMode(ListeningMode mode);
    
    /**
     * @brief 音频循环处理
     */
    void AudioLoop();
};

#endif // _APPLICATION_H_
